package com.bzy.common.aop.impl;

import com.bzy.common.aop.IBaseAspect;
import com.bzy.common.util.local.ExceptionUtil;
import com.bzy.common.util.local.ThreadLocalUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;


/* 1、preHandle
 * 2、around entry
 * 3、advice before
 * 4、controller method
 * 5、around exit
 * 6、advice after
 * 7、advice afterReturning
 * 8、postHandle
 * 9、afterCompletion
 */

@Aspect
@Component
public class ControllerBaseAspect implements IBaseAspect {

	@Pointcut("@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController)")
	public void pcWholeController() {
	}

	@Pointcut("@annotation(com.bzy.common.aop.ControllerLogger)")
	public void pcAnnotationController() {
	}

	@Override
	@Before("pcWholeController()")
	public void before(JoinPoint joinPoint) {
		// TODO Auto-generated method stub
		// execute no.3
	}

	@Override
	@After("pcWholeController()")
	public void after(JoinPoint joinPoint) {
		// TODO Auto-generated method stub
		// execute no.6
	}

	@Override
	@AfterReturning(value = "pcWholeController()", argNames = "returnObj", returning = "returnObj")
	public void afterReturning(JoinPoint joinPoint, Object returnObj) {
		// TODO Auto-generated method stub
		// execute no.7
	}

	@Override
	@AfterThrowing(value = "pcWholeController()", throwing = "e")
	public void afterThrowing(JoinPoint joinPoint, Throwable e) {
		// TODO Auto-generated method stub
//		LoggerUtil.error("ControllerBaseAspect.java--afterThrowing");
		e.printStackTrace();
	}

	@Override
	@Around("pcWholeController()")
	public Object around(ProceedingJoinPoint pJoinPoint) throws Throwable {
		// TODO Auto-generated method stub
		// filer->preHandle->entry around->before->method->exit
		// around->after->afterReturning->postHandle->afterCompletion
		// execute no.2 entry around
		Object o = null;
		try {
			// execute no.4 (controller method)
			o = pJoinPoint.proceed(pJoinPoint.getArgs());
			// execute no.5 (exit around)
		} catch (Throwable e) {
			 e.printStackTrace();

			o = ExceptionUtil.resolveException(e);

			// String callback = request.getParameter("callback");
			// if (!StringUtils.isBlank(callback)) {
			// MappingJacksonValue mappingJacksonValue = new
			// MappingJacksonValue(o);
			// mappingJacksonValue.setJsonpFunction(callback);
			// o = mappingJacksonValue;
			// }

			String exceptionString = ExceptionUtil.getExceptionContent(e);
//			LoggerUtil.error("ControllerBaseAspect.java--around\n" + exceptionString);
			ThreadLocalUtil.setExceptionString(exceptionString);
		}
		ThreadLocalUtil.setResponseObj(o);
		return o;
	}

}
